<template>
    <view class="file-picker">
        <view
            class="file-box"
            v-for="(item, index) in filesList"
            :key="index"
            :style="boxStyle"
        >
            <view class="file-box-content" :style="borderStyle">
                <image class="file-image" :src="item.fullurl"  mode="aspectFill" @click.stop="prviewImage(item, index)"></image>
                <view   v-if="delIcon && !readonly"  class="icon-del-box" @click.stop="delFile(index)" >
                    <view class="icon-del"></view>
                    <view class="icon-del rotate"></view>
                </view>
                <view  v-if=" (item.progress && item.progress !== 100) ||  item.progress === 0  " class="file-progress" >
                    <progress
                        class="file-progress-item"
                        :percent="item.progress === -1 ? 0 : item.progress"
                        stroke-width="4"
                        :backgroundColor="item.errMsg ? '#ff5a5f' : '#EBEBEB'"
                    />
                </view>
                <view
                    v-if="item.errMsg"
                    class="file-mask"
                    @click.stop="uploadFiles(item, index)"
                >
                    点击重试
                </view>
            </view>
        </view>
        <view
            v-if="filesList.length < limit && !readonly"
            class="file-box"
            :style="boxStyle"
        >
            <view
                class="file-box-content is-add"
                :style="borderStyle"
                @click="choose"
            >
                <slot>
                    <view class="icon-add"></view>
                    <view class="icon-add rotate"></view>
                </slot>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    emits: ['select', 'success', 'fail', 'progress', 'delete', 'update:images', 'input'],
    props: {
        uploadurl: {
            type: String,
            default () {
                return ''
            }
        },
        // #ifdef VUE3
        images: {
            type: [Array, Object],
            default () {
                return []
            }
        },
        // #endif
        // #ifndef VUE3
        value: {
            type: [Array, Object],
            default () {
                return []
            }
        },
        // #endif
        // 最大选择个数 ，h5只能限制单选或是多选
        limit: {
            type: [Number, String],
            default: 9
        },
         // 选择文件类型  image/video/all
        fileMediatype: {
            type: String,
            default: 'image'
        },
        imageStyles: {
            type: Object,
            default() {
                return {
                    width: "auto",
                    height: "auto",
                    border: {},
                };
            },
        },
        returnType: {
            type: String,
            default: 'array'
        },
        sizeType: {
            type: Array,
            default () {
                return ['original', 'compressed']
            }
        },
        // 文件类型筛选
        fileExtname: {
            type: [Array, String],
            default() {
                return [];
            },
        },
        delIcon: {
            type: Boolean,
            default: true,
        },
        readonly: {
            type: Boolean,
            default: false,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
    },
    watch: {
        // #ifndef VUE3
        value: {
            handler(newVal, oldVal) {
                 console.log('oldVal',oldVal);
                // this.setValue(newVal, oldVal)
                //this.localValue = newVal;
            },
        },
        // #endif
        // #ifdef VUE3
        images: {
            handler(newVal, oldVal) {
                // this.setValue(newVal, oldVal)
              //  this.localValue = newVal;
            },
        },
        // #endif
    },
    computed: {
        filesList() {
            let files = [];
            this.files.forEach((v) => {
                files.push(v);
            });
            return files;
        },
        showType() {
            if (this.fileMediatype === 'image') {
                return this.mode
            }
            return 'list'
        },
        limitLength() {
            if (this.returnType === 'object') {
                return 1
            }
            if (!this.limit) {
                return 1
            }
            if (this.limit >= 9) {
                return 9
            }
            return this.limit
        },
        styles() {
            let styles = {
                width: "auto",
                height: "auto",
                border: {},
            };
            return Object.assign(styles, this.imageStyles);
        },
        boxStyle() {
            const { width = "auto", height = "auto" } = this.styles;
            let obj = {};
            if (height === "auto") {
                if (width !== "auto") {
                    obj.height = this.value2px(width);
                    obj["padding-top"] = 0;
                } else {
                    obj.height = 0;
                }
            } else {
                obj.height = this.value2px(height);
                obj["padding-top"] = 0;
            }

            if (width === "auto") {
                if (height !== "auto") {
                    obj.width = this.value2px(height);
                } else {
                    obj.width = "33.3%";
                }
            } else {
                obj.width = this.value2px(width);
            }

            let classles = "";
            for (let i in obj) {
                classles += `${i}:${obj[i]};`;
            }
            return classles;
        },
        borderStyle() {
            let { border } = this.styles;
            let obj = {};
            if (typeof border === "boolean") {
                obj.border = border ? "1px #eee solid" : "none";
            } else {
                let width = (border && border.width) || 1;
                width = this.value2px(width);
                let radius = (border && border.radius) || 5;
                radius = this.value2px(radius);
                obj = {
                    "border-width": width,
                    "border-style": (border && border.style) || "solid",
                    "border-color": (border && border.color) || "#eee",
                    "border-radius": radius,
                };
            }
            let classles = "";
            for (let i in obj) {
                classles += `${i}:${obj[i]};`;
            }
            return classles;
        },
    },
    data() {
        return {
            files:[],
            localValue: [],
        }
    },
    methods: {
        delFile(index) {
            this.files.splice(index, 1)
            this.setEmit();
            this.$emit("delFile", index);
        },
        prviewImage(img, index) {
            let urls = [];
            if (
                Number(this.limit) === 1 &&
                this.disablePreview &&
                !this.disabled
            ) {
                this.$emit("choose");
            }
            if (this.disablePreview) return;
            this.filesList.forEach((i) => {
                urls.push(i.fullurl);
            });

            uni.previewImage({
                urls: urls,
                current: index,
            });
        },
        value2px(value) {
            if (typeof value === "number") {
                value += "px";
            } else {
                if (value.indexOf("%") === -1) {
                    value = value.indexOf("px") !== -1 ? value : value + "px";
                }
            }
            return value;
        },
         /**
         * 处理返回事件
         */
        setEmit() {
            let data = []
            let images = [];
            this.files.forEach(item=>{
                data = [...data,item.fullurl]
                images = [...images,item.url]
            })
            console.log(images);
            this.$emit('update:images', images)
            this.$emit('input', data)
          
        },
        choose() {
            // this.$emit("choose")
            if (this.disabled) return;
            if (this.files.length >= Number(this.limitLength)  &&  this.returnType === "array" ) {
               
                uni.showToast({
                    title: `您最多选择 ${this.limitLength} 个文件`,
                    icon: "none",
                });
                return;
            }
            let _that = this;
            //选择文件并上传
            this.chooseFiles().then(res=>{
               console.log(res);
                res.tempFilePaths.forEach(file=>{
                    let index = _that.files.length;
                    _that.files.push({fullurl:'',progress:index})
                    let uploadTask =  uni.uploadFile({
                        url: _that.uploadurl, //仅为示例，非真实的接口地址
                        header:{
                        },
                        filePath: file,
                        name: 'file',
                        success: (uploadFileRes) => {
                            if(uploadFileRes.data){ 
                                console.log(index);
                                let successData = JSON.parse(uploadFileRes.data).data 
                                _that.files[index].fullurl = successData.fullurl
                                _that.files[index].url = successData.url
                                _that.setEmit();
                                // console.log( _that.files);
                                
                            }
                        }
                    });
                    uploadTask.onProgressUpdate((res) => {
                        _that.files[index].progress = res.progress
                        // console.log('上传进度' + res.progress);
                        // console.log('已经上传的数据长度' + res.totalBytesSent);
                        // console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);

                        // 测试条件，取消上传任务。
                        // if (res.progress > 50) {
                        //     uploadTask.abort();
                        // }
                    });
                 
                })
           });

        },
        chooseFiles() {
            const _extname = this.get_extname(this.fileExtname);
            return new Promise((resolve, reject) => {
                uni.chooseImage({
                    type: this.fileMediatype,
                    compressed: false,
                    sizeType: this.sizeType,
                    // TODO 如果为空，video 有问题
                    extension: _extname.length > 0 ? _extname : undefined,
                    count: this.limitLength - this.files.length, //默认9
                    onChooseFile: this.chooseFileCallback,
                    success(res) {
                        resolve(
                            normalizeChooseAndUploadFileRes(res, "image")
                        );
                    },
                    fail(res) {
                        reject({
                            errMsg: res.errMsg.replace(
                                "chooseImage:fail",
                                ERR_MSG_FAIL
                            ),
                        });
                    },
                });
            });
            function normalizeChooseAndUploadFileRes(res, fileType) {
                res.tempFiles.forEach((item, index) => {
                    if (!item.name) {
                        item.name = item.path.substring(
                            item.path.lastIndexOf("/") + 1
                        );
                    }
                    if (fileType) {
                        item.fileType = fileType;
                    }
                    item.cloudPath =
                        Date.now() +
                        "_" +
                        index +
                        item.name.substring(item.name.lastIndexOf("."));
                });
                if (!res.tempFilePaths) {
                    res.tempFilePaths = res.tempFiles.map((file) => file.path);
                }
                return res;
            }

        },
        get_extname(fileExtname){
            if (!Array.isArray(fileExtname)) {
                let extname = fileExtname.replace(/(\[|\])/g, '')
                return extname.split(',')
            } else {
                return fileExtname
            }
            return []
        },
        
    },
}
</script>


<style scoped>
.file-picker {
    /* #ifndef APP-NVUE */
    display: flex;
    box-sizing: border-box;
    /* #endif */
    flex-wrap: wrap;
    margin: -5px;
}
.file-box {
    position: relative;
    /* flex: 0 0 33.3%; */
    width: 33.3%;
    height: 0;
    padding-top: 33.33%;
    /* #ifndef APP-NVUE */
    box-sizing: border-box;
    /* #endif */
}
.file-box-content {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: 5px;
    border: 1px #eee solid;
    border-radius: 8px;
    overflow: hidden;
}
.file-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    /* border: 1px red solid; */
    z-index: 2;
}

.file-progress-item {
    width: 100%;
}

.file-mask {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    justify-content: center;
    align-items: center;
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    left: 0;
    color: #fff;
    font-size: 12px;
    background-color: rgba(0, 0, 0, 0.4);
}
.file-image {
    width: 100%;
    height: 100%;
}
.is-add {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    align-items: center;
    justify-content: center;
}

.icon-add {
    width: 50px;
    height: 5px;
    background-color: #f1f1f1;
    border-radius: 2px;
}

.rotate {
    position: absolute;
    transform: rotate(90deg);
}

.icon-del-box {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 5px;
    right: 5px;
    height: 26px;
    width: 26px;
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 2;
    transform: rotate(-45deg);
}

.icon-del {
    width: 15px;
    height: 2px;
    background-color: #fff;
    border-radius: 2px;
}
</style>